A number of tasks executing in a microcontroller 20 (see FIGS. 1A and 1B) may take different paths (also called “code paths”) even if such tasks execute the same software program (also called “code”) 10. For example, Task0 may make a jump in executing code 10 after performing a first policing function at a location S0, thereby to define a first code path 11. Once Task0 makes the jump, Task0 does not need to perform the remaining policing functions S1 and S2 that are otherwise required during in-line (i.e. no jump) execution of software program 10.
In the example of FIG. 1A, another task, namely Task1 does not jump immediately after location S0 in software program 10, and instead continues with in-line execution (e.g. executes a number of instructions immediately following location S0). However, Task1 may eventually make a jump after performing a second policing function at a location S1 in the software program 10, thereby to define code path 12. In a similar manner, Task2 may simply execute software program 10 without making any jumps immediately after locations S0 and S1, thereby to define code path 13.
In the example being discussed, at various locations in the respective code paths, a decision to make a jump depends on the value of data that is shared among such tasks, Task0-Task2. For example, in a networking application, the policing functions performed at locations S0 and S1 may require that a packet that is being processed be dropped, for example if the rate exceeds a predefined bandwidth allocated to a channel to which the packet belongs.
Therefore, it is important for such tasks, Task0-Task2 to ensure that the data being used in the policing functions is accurate and updated properly. Access to such data may be arbitrated by use of a semaphore as a synchronization mechanism, to access a common location in memory, to ensure that data at that common location is not changed by one task while that data is being used by another task. Use of such a semaphore ensures, for example, that a packet counter is properly incremented (or a database entry is properly accessed) by each of a number of tasks that execute concurrently or simultaneously in the microcontroller.
In using a semaphore, when one task, e.g. Task0 in FIG. 1B, is accessing a memory location at a location S0 in the code, other tasks, e.g. Task1, Task2, and Task3, that also need to access that same memory location are suspended (i.e. are made to wait). While such other tasks are waiting, Task0 may be activated from sleep, may issue a read request on being awakened, may again be put to sleep while waiting for a response from memory, may again be awakened on receiving the memory response, perform a read operation, and finally release the semaphore. Only at this point is the semaphore for code location S0 available for use by the next task, Task1.
Therefore, use of a semaphore effectively single threads the access to a common memory location in all of the tasks, even though a microcontroller (such as a network processor) may support multitasking. Such single threading causes the latency of each task to affect all subsequently-performed tasks.
U.S. Pat. No. 5,790,881 granted to Nguyen on Aug. 4, 1998 entitled “Computer system including coprocessor devices simulating memory interfaces” suggests (see abstract) “coupling a coprocessor to a master device, in which the coprocessor emulates an memory interface to the master device, like that of a memory device . . . . The coprocessor is disposed to receive data written from the master device, perform a coprocessing function on that data, and respond to a read data command from the master device with processing results.”
See also U.S. Pat. No. 6,338,108 granted to Motomura on Jan. 8, 2002 entitled “Coprocessor-integrated packet-type memory LSI, packet-type memory/coprocessor bus, and control method thereof” which states (see abstract) that “[a] memory section and coprocessor sections in a coprocessor-integrated packet-type DRAM are provided with unique memory device ID and coprocessor device IDs respectively . . . ”